<?php

namespace server;

class webSocket {

    protected $server;

    public function __construct()
    {
        $this->server = new \Swoole\Websocket\Server("0.0.0.0", 9502);
    }

    public function setConfig(array $config = [])
    {
        if (!empty($config)) {
            $this->server->set($config);
        }
        return $this;
    }

    public function initialize()
    {
        require __DIR__ . '/../bootstrap/bootstrap.php';

        $this->server->on('open', array($this, 'open'));
        $this->server->on('message', array($this, 'message'));
        $this->server->on('close', array($this, 'close'));

        return $this;
    }

    public function open($server, $req)
    {
        $this->server->start();
    }

    public function message($server, $frame)
    {
        if ($data = json_decode($frame->data, true)) {
            if ($data['type'] == 'connect') {
                WebSocketTools::bindUser($frame->fd, ['username' => $data['username']]);
                $msg = $data['username'].'来到了该房间';
            } else {
                $msg = $data['username']. ':'. $data['msg'];
            }
            foreach ($server->connections as $r ) {
                if ($frame->fd == $r && $data['type'] == 'connect') {
                    WebSocketTools::sendMessage($server, $r, '加入房间成功');
                }
                if ($frame->fd != $r) {
                    WebSocketTools::sendMessage($server, $r, $msg);
                }

            }
        }
    }

    public function close($server, $fd)
    {
        $username = WebSocketTools::getUserInfo($fd)['username'];
        if (isset(WebSocketTools::$map[$fd])) unset(WebSocketTools::$map[$fd]);
        if ($server->connections) foreach ($server->connections as $r ) {
            if ($fd != $r) {
                WebSocketTools::sendMessage($server, $r, $username.'退出了聊天室');
            }
        }
    }

    public function run()
    {
        $this->server->start();
    }



}

class WebSocketTools {
    
    static $map = array();

    /**
     * 发送消息
     * @param $server
     * @param $fd
     * @param string $msg
     * @return mixed
     */
    public static function sendMessage($server, $fd, $msg = '')
    {
        return $server->push($fd, json_encode([
                        'list' => self::$map,
                        'count' => count(self::$map), 
                        'msg' => $msg
            ])
        );
    }

    /**
     * 获取用户信息
     * @param $fd
     * @return mixed | array
     */
    public static function getUserInfo($fd)
    {
        return isset(self::$map[$fd]) ? self::$map[$fd] : [];
    }

    /**
     * 绑定用户信息
     * @param $fd
     * @param $userInfo
     * @return mixed
     */
    public static function bindUser($fd, $userInfo)
    {
        return self::$map[$fd] = $userInfo;
    }
}



(new webSocket)->setConfig([
    'daemonize' => 1
])->initialize()->run();